using System;

namespace WenYu.Runtime
{
    /// <summary>
    /// 青春版标准库 - 面向初学者的标准库实现
    /// 
    /// 特点:
    /// - 详细的错误消息
    /// - 类型转换更宽松
    /// - 友好的提示信息
    /// - 教学友好的调试支持
    /// 
    /// 对标需求: REQ-06 青春版标准库
    /// </summary>
    public class YouthLibrary : IStandardLibrary
    {
        /// <summary>错误消息缓冲区（用于收集错误）</summary>
        private string _lastError = "";

        /// <summary>是否启用详细输出</summary>
        public bool VerboseMode { get; set; } = false;

        // ===== 核心标准库函数 =====

        /// <summary>
        /// 输出函数 - 将栈顶的值输出到控制台
        /// </summary>
        public void Print(ExecutionContext context, int count)
        {
            if (context == null)
                throw new ArgumentNullException(nameof(context));

            if (count < 0)
            {
                HandleError("输出个数不能为负数", context);
                return;
            }

            if (count == 0)
            {
                // 输出空值时不输出任何内容
                return;
            }

            try
            {
                // 检查栈中是否有足够的值
                if (context.OperandStackSize < count)
                {
                    HandleError($"栈中只有{context.OperandStackSize}个值，但要求输出{count}个值", context);
                    return;
                }

                // 弹出count个值并输出
                var values = new Value[count];
                for (int i = count - 1; i >= 0; i--)
                {
                    values[i] = context.PopOperand();
                }

                // 输出所有值（不带分隔符）
                foreach (var value in values)
                {
                    Console.Write(value.ToString());
                }

                // 添加换行符
                Console.WriteLine();
            }
            catch (Exception ex)
            {
                HandleError($"输出出错: {ex.Message}", context);
            }
        }

        /// <summary>
        /// 输入函数（预留）- Phase 2+实现
        /// </summary>
        public Value Read()
        {
            throw new NotImplementedException("输入函数在青春版v1.0中暂未实现，计划在Phase 2+ 中支持");
        }

        /// <summary>
        /// 确认函数 - 显示提示并等待用户输入是/否（青春版）
        /// </summary>
        public Value Confirm(string prompt)
        {
            const int maxRetries = 3;
            int retryCount = 0;

            while (retryCount < maxRetries)
            {
                // 显示提示信息
                Console.Write($"{prompt} (是/否 或 y/n): ");
                var input = Console.ReadLine()?.Trim().ToLower() ?? "";

                // 支持多种输入格式（青春版容错）
                if (input == "是" || input == "y" || input == "yes" || input == "1" || input == "真")
                {
                    return new Value(true);
                }
                else if (input == "否" || input == "n" || input == "no" || input == "0" || input == "假")
                {
                    return new Value(false);
                }
                else
                {
                    retryCount++;
                    if (retryCount < maxRetries)
                    {
                        Console.WriteLine($"😊 输入格式不对哦！请输入 '是' 或 '否'（剩余 {maxRetries - retryCount} 次机会）");
                    }
                    else
                    {
                        Console.WriteLine("❌ 输入错误次数太多，默认为 '否'");
                        return new Value(false);
                    }
                }
            }

            return new Value(false);
        }

        /// <summary>
        /// 输入带提示 - 显示提示信息后等待用户输入（青春版）
        /// </summary>
        public Value ReadWithPrompt(string prompt)
        {
            Console.Write(prompt);
            var input = Console.ReadLine() ?? "";
            return new Value(input);
        }

        /// <summary>
        /// 输入带默认值 - 如果用户直接回车则使用默认值（青春版）
        /// </summary>
        public Value ReadWithDefault(Value defaultValue)
        {
            Console.Write($"请输入（默认：{defaultValue}）: ");
            var input = Console.ReadLine()?.Trim() ?? "";

            // 如果用户直接回车，使用默认值
            if (string.IsNullOrWhiteSpace(input))
            {
                Console.WriteLine($"✅ 使用默认值：{defaultValue}");
                return defaultValue;
            }

            // 根据默认值类型，转换输入
            try
            {
                return ConvertToType(input, defaultValue.Type);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"⚠️ 输入格式错误（{ex.Message}），使用默认值：{defaultValue}");
                return defaultValue;
            }
        }

        /// <summary>
        /// 类型转换辅助函数 - 根据目标类型转换字符串输入
        /// </summary>
        private Value ConvertToType(string input, Value.ValueType targetType)
        {
            switch (targetType)
            {
                case Value.ValueType.Integer:
                    if (int.TryParse(input, out int intValue))
                        return new Value(intValue);
                    throw new FormatException($"无法将 '{input}' 转换为整数");

                case Value.ValueType.Float:
                    if (double.TryParse(input, out double doubleValue))
                        return new Value(doubleValue);
                    throw new FormatException($"无法将 '{input}' 转换为实数");

                case Value.ValueType.Boolean:
                    // 青春版容错：支持多种格式
                    var lower = input.ToLower();
                    if (lower == "真" || lower == "是" || lower == "true" || lower == "1" || lower == "y")
                        return new Value(true);
                    if (lower == "假" || lower == "否" || lower == "false" || lower == "0" || lower == "n")
                        return new Value(false);
                    throw new FormatException($"无法将 '{input}' 转换为真假值");

                case Value.ValueType.String:
                    return new Value(input);

                default:
                    return new Value(input);
            }
        }

        /// <summary>
        /// 类型转换：转换为文字
        /// </summary>
        public Value ToString(Value value)
        {
            if (value == null)
                return new Value("null");

            return new Value(value.ToString());
        }

        /// <summary>
        /// 获取数组长度（预留）- Phase 2+实现
        /// </summary>
        public Value GetLength(Value arrayValue)
        {
            throw new NotImplementedException("数组长度函数在青春版v1.0中暂未实现，计划在Phase 2+ 中支持");
        }

        /// <summary>
        /// 获取字符串长度
        /// </summary>
        public Value StringLength(Value stringValue)
        {
            if (stringValue == null)
                throw new ArgumentNullException(nameof(stringValue));

            if (!stringValue.IsString)
                throw new InvalidOperationException($"长度操作仅支持字符串类型，当前类型是: {stringValue.Type}");

            return new Value(stringValue.AsString().Length);
        }

        /// <summary>
        /// 错误处理 - 青春版提供友好的错误消息
        /// </summary>
        public void HandleError(string message, ExecutionContext context)
        {
            _lastError = message;

            // 输出错误前缀
            Console.ForegroundColor = ConsoleColor.Red;
            Console.Write("❌ 错误: ");
            Console.ResetColor();

            // 输出错误消息
            Console.WriteLine(message);

            // 青春版提供调试信息
            if (VerboseMode && context != null)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine($"💡 调试信息:");
                Console.WriteLine($"   - 指令指针: {context.InstructionPointer}");
                Console.WriteLine($"   - 操作数栈大小: {context.OperandStackSize}");
                Console.WriteLine($"   - 全局变量数: {context.GlobalCount}");
                Console.ResetColor();
            }

            // 根据错误提供建议
            ProvideHints(message);
        }

        // ===== 辅助方法 =====

        /// <summary>
        /// 根据错误类型提供学习建议
        /// </summary>
        private void ProvideHints(string errorMessage)
        {
            // 这是教学友好的功能 - 根据错误类型提供建议
            if (errorMessage.Contains("栈为空"))
            {
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("💡 提示: 栈是空的，说明没有足够的值来进行这个操作");
                Console.WriteLine("   确保先压入了足够的值到栈中");
                Console.ResetColor();
            }
            else if (errorMessage.Contains("未定义"))
            {
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("💡 提示: 使用了未定义的变量");
                Console.WriteLine("   确保变量已经被声明和赋值");
                Console.ResetColor();
            }
            else if (errorMessage.Contains("类型"))
            {
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("💡 提示: 类型不匹配");
                Console.WriteLine("   检查操作数的类型是否合适");
                Console.ResetColor();
            }
            else if (errorMessage.Contains("零"))
            {
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("💡 提示: 除以零或模零");
                Console.WriteLine("   不能用零作为除数或模数");
                Console.ResetColor();
            }
        }

        /// <summary>
        /// 获取最后一次的错误消息
        /// </summary>
        public string GetLastError()
        {
            return _lastError;
        }

        /// <summary>
        /// 清空错误消息
        /// </summary>
        public void ClearError()
        {
            _lastError = "";
        }
    }
}
